#include <algorithm>
#include "vertex_factory.hpp"

vv::vertex_factory::~vertex_factory() {
  for (vpiter i = pool.begin(); i != pool.end(); ++i) {
    delete *i;
  }  
}

vv::vptr vv::vertex_factory::create_vertex() {
  abstract_vertex* v = allocate_vertex();
  pool.insert(v);
  return v;
}

void vv::vertex_factory::collect_garbage() {
  for (vpiter i = pool.begin(); i != pool.end(); ++i)
    (*i)->gc_mark = (*i)->references() ? true : false;

  for (vpiter i = pool.begin(); i != pool.end(); ++i)
    if ((*i)->gc_mark)
      recurse_mark(*i);

  for (vpiter i = pool.begin(); i != pool.end(); ++i) {
    if (!(*i)->gc_mark) {
      delete *i;
      pool.erase(i);
    }
  }
}

unsigned int vv::vertex_factory::count() {
  return pool.size();
}

void vv::vertex_factory::recurse_mark(vv::abstract_vertex* v) {
  if (v->valence() == 0) return;
  iptr i(v->iter());
  for (vptr v = i->first(); i->not_finished(); v = i->advance())
    if (!v->gc_mark) {
      v->gc_mark = true;
      recurse_mark(v.raw());
    }
}
